/**
 * Created by chencheng on 2017/6/16.
 */
import { isEmpty } from './checkType';

/**
 * 深度合并对象
 * 文档说明: https://github.com/KyleAMathews/deepmerge
 */
import deepmerge from './deepmerge';
export {deepmerge}
/**
 * 深度clone
 */
import deepClone from './deepClone';
export {deepClone}

/**
 * 跳转页面
 * @param url
 * @param timeout
 */
export const redirect = (url: string, timeout: number) => {
    setTimeout(function () {
        location.href = url || location.href;
    }, timeout || 0);
};


/**
 * 时间格式化
 */
export const dateFormat = (timestamp: number|string, fmt = "yyyy-MM-dd hh:mm:ss") => {
    if (!timestamp) return "-";

    if(timestamp.toString().length == 10){
        timestamp = timestamp as number * 1000
    }
    const date = new Date(timestamp);

    const o = {
        "y+": date.getFullYear(),
        "M+": date.getMonth() + 1,                  //月份
        "d+": date.getDate(),                       //日
        "h+": date.getHours(),                      //小时
        "m+": date.getMinutes(),                    //分
        "s+": date.getSeconds(),                    //秒
        "q+": Math.floor((date.getMonth() + 3) / 3), //季度
        "S+": date.getMilliseconds()                 //毫秒
    };

    for (let k in o) {
        if (new RegExp("(" + k + ")").test(fmt)){
            if(k == "y+"){
                fmt = fmt.replace(RegExp.$1, ("" + o[k]).substr(4 - RegExp.$1.length));
            }
            else if(k=="S+"){
                var lens = RegExp.$1.length;
                lens = lens==1 ? 3 : lens;
                fmt = fmt.replace(RegExp.$1, ("00" + o[k]).substr(("" + o[k]).length - 1,lens));
            }
            else{
                // @ts-ignore
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
        }
    }

    return fmt;
};

/**
 * 数组去重
 */
export const uniq = <T>(data: T[]): T[] => Array.from(new Set(data));

/**
 * 转换数组为对象
 */
export const convertArrayToObj = <V = any>(data: V[], extractValueName = "value") => {
    const result:{[index: string]: V} = {}
    // @ts-ignore
    data.forEach(item => result[item[extractValueName]] = item);
    return result;
}

/**
 * 空数值默认显示
 */
export const defaultTo = <V = any>(data: V, defaultVal: any):V => isEmpty(data) ? defaultVal : data;

/**
 * 获取a数组不同于b数组的元素
 */
export const differenceOfArray = <T = any>(a: T[], b: T[]) => [...a].filter(x => !b.includes(x));

/**
 * 获取a数组的元素在b数组中存在的元素
 */
export const sameOfArray = <T = any>(a: T[], b: T[]) => [...a].filter(x => b.includes(x));

/**
 * 减速节流函数
 * @param {Function} fn 需要延迟执行的函数
 * @param {Number} time 延迟时间毫秒
 * @param {Object} context
 * @return {wrapperFn}
 *
 * usage:
     const a_fn = (params) => {}
     const render = throttle(a_fn, 16, null);
     render(1);
     render(2); // 将延迟16毫秒执行
 */
export const throttle = (fn: Function, time = 100, context?: any) => {
    let lock: boolean, args: boolean | any[];

    function later () {
        // reset lock and call if queued
        lock = false;
        if (args) {
            wrapperFn.apply(context, args);
            args = false;
        }
    }

    function wrapperFn (...rest: any[]) {
        if (lock) {
            // called too soon, queue to call later
            args = rest;

        } else {
            // lock until later then call
            lock = true;
            fn.apply(context, rest);
            setTimeout(later, time);
        }
    }

    return wrapperFn;
};


/**
 * 防抖函数
 * @param {Function} fn     回调函数
 * @param {Number} delay    延迟时间
 * @param {Object} [context]  回调函数上下文
 * @returns {Function}
 */
export const debounce = (fn: Function, delay = 100, context?: any) => {
    let timeout: any;

    return function(...args: any[]){

        clearTimeout(timeout);

        context = context || this;
        // let args = arguments

        timeout = setTimeout(function(){

            fn.apply(context, args);

        },delay)

    };
};

export const isInnerIp = (ip: string) => {
    return /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/.test(ip)
}

/**
 * 生成随机字符串
 */
export const randomString = (length: number = 4) => {
    const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let result = '';
    for (let i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
    return result;
};


/**
 * 将Blod转成String
 */
export const blobToString = (blob: Blob, characterSet: string = 'utf-8') => new Promise((resolve, reject)=> {
    const reader = new FileReader();
    reader.readAsText(blob, characterSet);
    reader.onload = () => {
        resolve(reader.result);
    };

    reader.onerror = (e) => {
        reject(e);
    };
});

/**
 * 下载文件
 * @param {String} content 下载内容
 * @param {String} fileName 文件名称
 */
export const downloadFile = (content: string = "", fileName: string = "") => {
    const blob = new Blob([content]);

    const a = document.createElement("a");
    a.href = window.URL.createObjectURL(blob);
    a.download = fileName;

    document.querySelector('body').appendChild(a);
    a.click();
    document.querySelector('body').removeChild(a)
};
